package com.manpower.configuraion;

import com.alibaba.fastjson.JSONObject;
import com.manpower.common.Log;
import com.manpower.constant.Constants;
import com.manpower.dao.dataobject.sys.SysLogDto;
import com.manpower.dao.mapper.SysLogDtoMapper;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 统一日志处理
 * @ClassName LogAspect
 * @Author weiyong.wang
 * @Date 2020/8/17
 */
@Aspect
@Configuration
@Component
public class LogAspect {
    private static Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Autowired
    private SysLogDtoMapper logDao;


    @Pointcut("execution(public * com.manpower.web..*(..))")
    public void webLog() {
    }

    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
    }

    @AfterReturning(value = "webLog()", returning = "ret")
    public void doAfterReturning(Object ret) throws Throwable {
    }

    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long endTime = System.currentTimeMillis();
        try {

            //获取当前请求对象
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            if(attributes==null){//为空标识可能是定时器或其他异步线程处理
                return result;
            }
            HttpServletRequest request = attributes.getRequest();

            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature) signature;
            Method method = methodSignature.getMethod();

            Log log = method.getAnnotation(Log.class);
            System.out.println(log.type());

            String reqParamInfo = JSONObject.toJSONString(getParameter(joinPoint.getArgs()));
            if(StringUtils.isNotBlank(reqParamInfo) && reqParamInfo.length()>2000){
                reqParamInfo = reqParamInfo.substring(0,1999);
            }

            //记录请求信息
            SysLogDto logDto = new SysLogDto();
            logDto.setLogType(Constants.LOGTYPE_HANDLE); //操作日志
            logDto.setLogModule(method.getName());
            logDto.setLogIp(request.getRemoteAddr());
            logDto.setLogInfo(reqParamInfo); //请求参数
            logDto.setKeepTime(0);//不清除日志
            logDto.setCreateUser(null);
            logDto.setCreateTime(new Date());
            logDto.setReservedField1(request.getMethod()); //请求方法
            logDto.setReservedField2(request.getRequestURI()); //请求路径

            String returnInfo = JSONObject.toJSONString(result);
            if(StringUtils.isNotBlank(returnInfo) && returnInfo.length()>200){
                returnInfo = returnInfo.substring(0,199);
            }
            logDto.setReservedField3(returnInfo); //返回内容
            logDto.setReservedField4("用时："+(endTime-startTime)+"毫秒");

            logDao.insert(logDto);
        }catch (Exception e){
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 根据方法和传入的参数获取请求参数
     */
    private Object getParameter(Object[] args) {

        // 构造参数组集合
        List<Object> argList = new ArrayList<>();
        for (Object arg : args) {
            // request/response无法使用toJSON
            if (arg instanceof HttpServletRequest) {
                argList.add("request");
            } else if (arg instanceof HttpServletResponse) {
                argList.add("response");
            } else {
                argList.add(JSONObject.toJSON(arg));
            }
        }
        return argList;

        /*List<Object> argList = new ArrayList<>();
        Parameter[] parameters = method.getParameters();
        for (int i = 0; i < parameters.length; i++) {
            //将RequestBody注解修饰的参数作为请求参数
            RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
            if (requestBody != null) {
                argList.add(args[i]);
            }
            //将RequestParam注解修饰的参数作为请求参数
            RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
            if (requestParam != null) {
                Map<String, Object> map = new HashMap<>();
                String key = parameters[i].getName();
                if (!StringUtils.isEmpty(requestParam.value())) {
                    key = requestParam.value();
                }
                map.put(key, args[i]);
                argList.add(map);
            }


        }
        if (argList.size() == 0) {
            return null;
        } else if (argList.size() == 1) {
            return argList.get(0);
        } else {
            return argList;
        }*/
    }

}
